<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Contour Features</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d5/d10/tutorial_js_root.html">OpenCV.js Tutorials</a></li><li class="navelem"><a class="el" href="../../d2/df0/tutorial_js_table_of_contents_imgproc.html">Image Processing</a></li><li class="navelem"><a class="el" href="../../d0/d43/tutorial_js_table_of_contents_contours.html">Contours in OpenCV.js</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Contour Features </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h2>Goal </h2>
<ul>
<li>To find the different features of contours, like area, perimeter, centroid, bounding box etc</li>
<li>You will learn plenty of functions related to contours.</li>
</ul>
<h2>1. Moments </h2>
<p>Image moments help you to calculate some features like center of mass of the object, area of the object etc. Check out the wikipedia page on <a href="http://en.wikipedia.org/wiki/Image_moment">Image Moments</a></p>
<p>We use the function: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga556a180f43cab22649c23ada36a8a139" title="Calculates all of the moments up to the third order of a polygon or rasterized shape. ">cv.moments</a> (array, binaryImage = false)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">array</td><td>raster image (single-channel, 8-bit or floating-point 2D array) or an array ( 1×N or N×1 ) of 2D points. </td></tr>
    <tr><td class="paramname">binaryImage</td><td>if it is true, all non-zero image pixels are treated as 1's. The parameter is used for images only.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_moments.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<p>From this moments, you can extract useful data like area, centroid etc. Centroid is given by the relations, \(C_x = \frac{M_{10}}{M_{00}}\) and \(C_y = \frac{M_{01}}{M_{00}}\). This can be done as follows: </p><div class="fragment"><div class="line">let cx = M.m10/M.m00</div><div class="line">let cy = M.m01/M.m00</div></div><!-- fragment --><h2>2. Contour Area </h2>
<p>Contour area is given by the function <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga2c759ed9f497d4a618048a2f56dc97f1" title="Calculates a contour area. ">cv.contourArea()</a></b> or from moments, <b>M['m00']</b>.</p>
<p>We use the function: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga2c759ed9f497d4a618048a2f56dc97f1" title="Calculates a contour area. ">cv.contourArea</a> (contour, oriented = false)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">contour</td><td>input vector of 2D points (contour vertices) </td></tr>
    <tr><td class="paramname">oriented</td><td>oriented area flag. If it is true, the function returns a signed area value, depending on the contour orientation (clockwise or counter-clockwise). Using this feature you can determine orientation of a contour by taking the sign of an area. By default, the parameter is false, which means that the absolute value is returned.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_area.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>3. Contour Perimeter </h2>
<p>It is also called arc length. It can be found out using <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga8d26483c636be6b35c3ec6335798a47c" title="Calculates a contour perimeter or a curve length. ">cv.arcLength()</a></b> function.</p>
<p>We use the function: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga8d26483c636be6b35c3ec6335798a47c" title="Calculates a contour perimeter or a curve length. ">cv.arcLength</a> (curve, closed)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">curve</td><td>input vector of 2D points. </td></tr>
    <tr><td class="paramname">closed</td><td>flag indicating whether the curve is closed or not.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_perimeter.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>4. Contour Approximation </h2>
<p>It approximates a contour shape to another shape with less number of vertices depending upon the precision we specify. It is an implementation of <a href="http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm">Douglas-Peucker algorithm</a>. Check the wikipedia page for algorithm and demonstration.</p>
<p>We use the function: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga0012a5fdaea70b8a9970165d98722b4c" title="Approximates a polygonal curve(s) with the specified precision. ">cv.approxPolyDP</a> (curve, approxCurve, epsilon, closed)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">curve</td><td>input vector of 2D points stored in <a class="el" href="../../d3/d63/classcv_1_1Mat.html" title="n-dimensional dense array class ">cv.Mat</a>. </td></tr>
    <tr><td class="paramname">approxCurve</td><td>result of the approximation. The type should match the type of the input curve. </td></tr>
    <tr><td class="paramname">epsilon</td><td>parameter specifying the approximation accuracy. This is the maximum distance between the original curve and its approximation. </td></tr>
    <tr><td class="paramname">closed</td><td>If true, the approximated curve is closed (its first and last vertices are connected). Otherwise, it is not closed.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_approxPolyDP.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>5. Convex Hull </h2>
<p>Convex Hull will look similar to contour approximation, but it is not (Both may provide same results in some cases). Here, <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga014b28e56cb8854c0de4a211cb2be656" title="Finds the convex hull of a point set. ">cv.convexHull()</a></b> function checks a curve for convexity defects and corrects it. Generally speaking, convex curves are the curves which are always bulged out, or at-least flat. And if it is bulged inside, it is called convexity defects. For example, check the below image of hand. Red line shows the convex hull of hand. The double-sided arrow marks shows the convexity defects, which are the local maximum deviations of hull from contours.</p>
<div class="image">
<img src="../../convexitydefects.jpg" alt="convexitydefects.jpg"/>
<div class="caption">
image</div></div>
<p> We use the function: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga014b28e56cb8854c0de4a211cb2be656" title="Finds the convex hull of a point set. ">cv.convexHull</a> (points, hull, clockwise = false, returnPoints = true)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">points</td><td>input 2D point set. </td></tr>
    <tr><td class="paramname">hull</td><td>output convex hull. </td></tr>
    <tr><td class="paramname">clockwise</td><td>orientation flag. If it is true, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise. The assumed coordinate system has its X axis pointing to the right, and its Y axis pointing upwards. </td></tr>
    <tr><td class="paramname">returnPoints</td><td>operation flag. In case of a matrix, when the flag is true, the function returns convex hull points. Otherwise, it returns indices of the convex hull points.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_convexHull.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>6. Checking Convexity </h2>
<p>There is a function to check if a curve is convex or not, <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga8abf8010377b58cbc16db6734d92941b" title="Tests a contour convexity. ">cv.isContourConvex()</a></b>. It just return whether True or False. Not a big deal.</p>
<div class="fragment"><div class="line">cv.isContourConvex(cnt);</div></div><!-- fragment --><h2>7. Bounding Rectangle </h2>
<p>There are two types of bounding rectangles.</p>
<h3>7.a. Straight Bounding Rectangle</h3>
<p>It is a straight rectangle, it doesn't consider the rotation of the object. So area of the bounding rectangle won't be minimum.</p>
<p>We use the function: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga103fcbda2f540f3ef1c042d6a9b35ac7" title="Calculates the up-right bounding rectangle of a point set or non-zero pixels of gray-scale image...">cv.boundingRect</a> (points)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">points</td><td>input 2D point set.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_boundingRect.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h3>7.b. Rotated Rectangle</h3>
<p>Here, bounding rectangle is drawn with minimum area, so it considers the rotation also.</p>
<p>We use the function: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga3d476a3417130ae5154aea421ca7ead9" title="Finds a rotated rectangle of the minimum area enclosing the input 2D point set. ">cv.minAreaRect</a> (points)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">points</td><td>input 2D point set.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_minAreaRect.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>8. Minimum Enclosing Circle </h2>
<p>Next we find the circumcircle of an object using the function <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga8ce13c24081bbc7151e9326f412190f1" title="Finds a circle of the minimum area enclosing a 2D point set. ">cv.minEnclosingCircle()</a></b>. It is a circle which completely covers the object with minimum area.</p>
<p>We use the functions: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#ga8ce13c24081bbc7151e9326f412190f1" title="Finds a circle of the minimum area enclosing a 2D point set. ">cv.minEnclosingCircle</a> (points)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">points</td><td>input 2D point set.</td></tr>
  </table>
  </dd>
</dl>
<p><b><a class="el" href="../../d6/d6e/group__imgproc__draw.html#gaf10604b069374903dbd0f0488cb43670" title="Draws a circle. ">cv.circle</a> (img, center, radius, color, thickness = 1, lineType = <a class="el" href="../../d6/d6e/group__imgproc__draw.html#ggaf076ef45de481ac96e0ab3dc2c29a777a5d32eda7017db273a37f158e5b51442a" title="8-connected line ">cv.LINE_8</a>, shift = 0)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">img</td><td>image where the circle is drawn. </td></tr>
    <tr><td class="paramname">center</td><td>center of the circle. </td></tr>
    <tr><td class="paramname">radius</td><td>radius of the circle. </td></tr>
    <tr><td class="paramname">color</td><td>circle color. </td></tr>
    <tr><td class="paramname">thickness</td><td>thickness of the circle outline, if positive. Negative thickness means that a filled circle is to be drawn. </td></tr>
    <tr><td class="paramname">lineType</td><td>type of the circle boundary. </td></tr>
    <tr><td class="paramname">shift</td><td>number of fractional bits in the coordinates of the center and in the radius value.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_minEnclosingCircle.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>9. Fitting an Ellipse </h2>
<p>Next one is to fit an ellipse to an object. It returns the rotated rectangle in which the ellipse is inscribed. We use the functions: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#gaf259efaad93098103d6c27b9e4900ffa" title="Fits an ellipse around a set of 2D points. ">cv.fitEllipse</a> (points)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">points</td><td>input 2D point set.</td></tr>
  </table>
  </dd>
</dl>
<p><b>cv.ellipse1 (img, box, color, thickness = 1, lineType = <a class="el" href="../../d6/d6e/group__imgproc__draw.html#ggaf076ef45de481ac96e0ab3dc2c29a777a5d32eda7017db273a37f158e5b51442a" title="8-connected line ">cv.LINE_8</a>)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">img</td><td>image. </td></tr>
    <tr><td class="paramname">box</td><td>alternative ellipse representation via RotatedRect. This means that the function draws an ellipse inscribed in the rotated rectangle. </td></tr>
    <tr><td class="paramname">color</td><td>ellipse color. </td></tr>
    <tr><td class="paramname">thickness</td><td>thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn. </td></tr>
    <tr><td class="paramname">lineType</td><td>type of the ellipse boundary.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_fitEllipse.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>10. Fitting a Line </h2>
<p>Similarly we can fit a line to a set of points. We can approximate a straight line to it.</p>
<p>We use the functions: <b><a class="el" href="../../d3/dc0/group__imgproc__shape.html#gaf849da1fdafa67ee84b1e9a23b93f91f" title="Fits a line to a 2D or 3D point set. ">cv.fitLine</a> (points, line, distType, param, reps, aeps)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">points</td><td>input 2D point set. </td></tr>
    <tr><td class="paramname">line</td><td>output line parameters. It should be a Mat of 4 elements[vx, vy, x0, y0], where [vx, vy] is a normalized vector collinear to the line and [x0, y0] is a point on the line. </td></tr>
    <tr><td class="paramname">distType</td><td>distance used by the M-estimator(see <a class="el" href="../../d7/d1b/group__imgproc__misc.html#gaa2bfbebbc5c320526897996aafa1d8eb">cv.DistanceTypes</a>). </td></tr>
    <tr><td class="paramname">param</td><td>numerical parameter ( C ) for some types of distances. If it is 0, an optimal value is chosen. </td></tr>
    <tr><td class="paramname">reps</td><td>sufficient accuracy for the radius (distance between the coordinate origin and the line). </td></tr>
    <tr><td class="paramname">aeps</td><td>sufficient accuracy for the angle. 0.01 would be a good default value for reps and aeps.</td></tr>
  </table>
  </dd>
</dl>
<p><b><a class="el" href="../../d6/d6e/group__imgproc__draw.html#ga7078a9fae8c7e7d13d24dac2520ae4a2" title="Draws a line segment connecting two points. ">cv.line</a> (img, pt1, pt2, color, thickness = 1, lineType = <a class="el" href="../../d6/d6e/group__imgproc__draw.html#ggaf076ef45de481ac96e0ab3dc2c29a777a5d32eda7017db273a37f158e5b51442a" title="8-connected line ">cv.LINE_8</a>, shift = 0)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">img</td><td>image. </td></tr>
    <tr><td class="paramname">pt1</td><td>first point of the line segment. </td></tr>
    <tr><td class="paramname">pt2</td><td>second point of the line segment. </td></tr>
    <tr><td class="paramname">color</td><td>line color. </td></tr>
    <tr><td class="paramname">thickness</td><td>line thickness. </td></tr>
    <tr><td class="paramname">lineType</td><td>type of the line,. </td></tr>
    <tr><td class="paramname">shift</td><td>number of fractional bits in the point coordinates.</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_contour_features_fitLine.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
 </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:37 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
